#include "ring_buf.h"

int ring_buf_init(ring_buf_t* ring_buf, char* buf, uint32_t buf_size)
{
    if (!RING_BUFFER_IS_POWER_OF_TWO(buf_size)) {
        return 0;
    }

    ring_buf->buffer = buf;
    ring_buf->buffer_mask = buf_size - 1;
    ring_buf->tail_index = 0;
    ring_buf->head_index = 0;

    return 1;
}

void ring_buf_queue(ring_buf_t* buffer, char data)
{
    if (ring_buf_is_full(buffer)) {
        /* 覆盖尾节点, 尾指数+1 */
        buffer->tail_index = ((buffer->tail_index + 1) & RING_BUFFER_MASK(buffer));
    }

    buffer->buffer[buffer->head_index] = data;
    buffer->head_index = ((buffer->head_index + 1) & RING_BUFFER_MASK(buffer));
}

void ring_buf_queue_arr(ring_buf_t* buffer, const char* arr, uint32_t arr_size)
{
    for (uint32_t i = 0; i < arr_size; i++) {
        ring_buf_queue(buffer, arr[i]);
    }
}

int ring_buf_dequeue(ring_buf_t* buffer, char* data)
{
    if (ring_buf_is_empty(buffer)) {
        return 0;
    }

    *data = buffer->buffer[buffer->tail_index];
    buffer->tail_index = ((buffer->tail_index + 1) & RING_BUFFER_MASK(buffer));

    return 1;
}

uint32_t ring_buf_dequeue_arr(ring_buf_t* buffer, char* arr, uint32_t len)
{
    if (ring_buf_is_empty(buffer)) {
        return 0;
    }

    char *data_ptr = arr;
    uint32_t cnt = 0;
    while ((cnt < len) && ring_buf_dequeue(buffer, data_ptr)) {
        cnt++;
        data_ptr++;
    }

    return cnt;
}

uint8_t ring_buf_peek(ring_buf_t* buffer, char* data, uint32_t index)
{
    if (index >= ring_buf_num_items(buffer)) {
        return 0;
    }

    uint32_t data_index = ((buffer->tail_index + index) & RING_BUFFER_MASK(buffer));
    *data = buffer->buffer[data_index];

    return 1;
}
